/*
 * rosa_semaphores.c
 *
 * Created: 2014-12-03 13:33:13
 *  Author: Andreas Domfors
 */ 

#include <stdbool.h>
#include "API/rosa_semaphores.h"
#include "kernel/rosa_systick.h"

typedef struct {
	bool semaphoreIsSignalled;
	tcb *firstTaskThatIsBlockedByThisSemaphore;
	semaphore *next;
	} semaphoreImpl;

static semaphoreImpl *semaphoreListHead = NULL;

/// Creates and initializes a semaphore at the specified
/// address. The semaphore is available when created.
int ROSA_createBinarySemaphore(semaphore *s)
{
	*s = malloc(sizeof(semaphoreImpl));
	if(*s == NULL)
		return -1;
	
	semaphoreImpl *new = *s;
	new->next = NULL;
	new->firstTaskThatIsBlockedByThisSemaphore = NULL;
	new->semaphoreIsSignalled = true;
	
	if(semaphoreListHead == NULL)
		semaphoreListHead = new;
	else
	{
		semaphoreImpl *iterator = semaphoreListHead;
		while(iterator->next != NULL)
			iterator = iterator->next;
		iterator->next = new;
	}
}

/* If the semaphore is available, then take it and return. Otherwise put 
the current task in the blocked list (possibly with a timeout), and then 
call the scheduler to do a context switch. */
int ROSA_waitBinarySemaphore(semaphore *s, unsigned int timeout)
{
	stopSysTick();
	
	startSysTick();
}

/// Signals the specified binary semaphore.
int ROSA_signalBinarySemaphore(semaphore *s);


/// Creates and initializes an IPCP semaphore at the location s.
/// The semaphore is available when created.
int ROSA_createSemaphoreIPCP(IPCPsemaphore *s, unsigned int ceiling);

/// Waits for the specified IPCP semaphore. If (timeout) ticks
/// pass without the semaphore becoming available, the operation
/// times out.
int ROSA_waitSemaphoreIPCP(IPCPsemaphore *s, unsigned int timeout);

/// Signals the specified IPCP semaphore. The task that calls this must
/// be the last task that successfully waited for the semaphore.
int ROSA_signalSemaphoreIPCP(IPCPsemaphore *s);